package org.elastic.compreplatform.quartz.controller;

import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.elastic.compreplatform.common.constant.RespEnum;
import org.elastic.compreplatform.common.model.PageHelper;
import org.elastic.compreplatform.common.model.RespMsg;
import org.elastic.compreplatform.common.util.DateUtil;
import org.elastic.compreplatform.common.util.PageHelperUtil;
import org.elastic.compreplatform.common.util.RespMsgUtil;
import org.elastic.compreplatform.quartz.core.schedule.JobDynamicScheduler;
import org.elastic.compreplatform.quartz.dao.JobGroupDao;
import org.elastic.compreplatform.quartz.dao.JobInfoDao;
import org.elastic.compreplatform.quartz.dao.JobLogDao;
import org.elastic.compreplatform.quartz.model.JobGroup;
import org.elastic.compreplatform.quartz.model.JobInfo;
import org.elastic.compreplatform.quartz.model.JobLog;
import org.elastic.compreplatform.quartz.service.JobService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.github.pagehelper.Page;
import com.minstone.quartz.core.biz.ExecutorBiz;
import com.minstone.quartz.core.biz.model.LogResult;
import com.minstone.quartz.core.biz.model.ReturnT;

/**
 * ClassName: JobLogController 
 * @Description: 
 * @author JornTang
 * @email 957707261@qq.com
 * @date 2017年8月17日
 */
@Controller
@RequestMapping("/joblog")
public class JobLogController {
	private static Logger logger = LoggerFactory.getLogger(JobLogController.class);

	@Resource
	private JobGroupDao jobGroupDao;
	@Resource
	public JobInfoDao jobInfoDao;
	@Resource
	public JobLogDao jobLogDao;
	@Resource
	private JobService jobService;
	
	/**
	 * @Description: 任务执行报表
	 * @return RespMsg 
	 * @throws
	 * @author JornTang
	 * @date 2018年2月9日
	 */
	@RequestMapping("/triggerChart")
	@ResponseBody
	public RespMsg triggerChartDate() {
		return jobService.triggerChartDate();
    }
	/**
	 * @Description: 获取统计信息
	 * @param model
	 * @return   
	 * @return RespMsg  
	 * @throws
	 * @author JornTang
	 * @date 2018年2月9日
	 */
	@RequestMapping("/dashboardInfo.do")
	@ResponseBody
	public RespMsg dashboardInfo() {
		Map<String, Object> dashboardMap = jobService.dashboardInfo();
		return RespMsgUtil.returnMsg(RespEnum.SUCCESS, null, dashboardMap);
	}
	/**
	 * @Description: 跳转到任务执行报表页面
	 * @return ModelAndView  
	 * @throws
	 * @author JornTang
	 * @date 2018年2月9日
	 */
	@RequestMapping("/toTriggerChartDate")
	public ModelAndView toTriggerChartDate() {
		ModelAndView view = new ModelAndView();
		view.setViewName("quartz/joblog/joblog-chart");
		return view;
    }
	/**
	 * @Description: 跳转到日志首页
	 * @param model
	 * @return String  
	 * @throws
	 * @author JornTang
	 * @date 2018年2月8日
	 */
	@RequestMapping("/index.do")
	public String index(Model model) {
		//执行器列表
		List<JobGroup> jobGroupList =  jobGroupDao.findAll();
		model.addAttribute("JobGroupList", jobGroupList);
		return "quartz/joblog/joblog-index";
	}
	/**
	 * @Description: 根据分组获取任务列表
	 * @param jobGroup
	 * @return   
	 * @throws
	 * @author JornTang
	 * @date 2018年2月8日
	 */
	@RequestMapping("/getJobsByGroup.do")
	@ResponseBody
	public RespMsg getJobsByGroup(int jobGroup){
		List<JobInfo> list = jobInfoDao.getJobsByGroup(jobGroup);
		return RespMsgUtil.returnMsg(RespEnum.SUCCESS, null, list);
	}
	/**
	 * @Description: 日志分页查询
	 * @param start
	 * @param length
	 * @param jobGroup
	 * @param jobId
	 * @param logStatus
	 * @param filterTime
	 * @return   
	 * @return Map<String,Object>  
	 * @throws
	 * @author JornTang
	 * @date 2018年2月8日
	 */
	@RequestMapping("/pageList.do")
	@ResponseBody
	public PageHelper pageList(PageHelper page,Integer jobGroup, Integer jobId, Integer logStatus, Integer filterType) {
		
		// parse param
		String filterTime = doFilterTime(filterType);
		Date triggerTimeStart = null;
		Date triggerTimeEnd = null;
		if (StringUtils.isNotBlank(filterTime)) {
			String[] temp = filterTime.split(" - ");
			if (temp!=null && temp.length == 2) {
				try {
					triggerTimeStart = DateUtils.parseDate(temp[0], new String[]{"yyyy-MM-dd HH:mm:ss"});
					triggerTimeEnd = DateUtils.parseDate(temp[1], new String[]{"yyyy-MM-dd HH:mm:ss"});
				} catch (ParseException e) {	}
			}
		}
		
		// page query
		Page<JobLog> list = jobLogDao.pageList(page.getOffset(), page.getLimit(), jobGroup, jobId, triggerTimeStart, triggerTimeEnd, logStatus,page.getSortColumns());
		return PageHelperUtil.doHandlePage(list);
	}
	/**
	 * @Description: 处理调度时间
	 * @param filterType
	 * @return   
	 * @return String  
	 * @throws
	 * @author JornTang
	 * @date 2018年2月9日
	 */
	private String doFilterTime(Integer filterType) {
		if(filterType == null){
			return null;
		}
		switch (filterType) {
		//全部
		case -1:
			return null;
		//最近1小时
		case 1:
			String beforeTime = DateUtil.beforeHour(1);
			return beforeTime + " - " + DateUtil.currentTime();
		//今日
		case 2:
			String currentTime = com.xiaoleilu.hutool.date.DateUtil.format(new Date(), "yyyy-MM-dd");
			return currentTime + " 00:00:00" + " - " + currentTime + " 23:59:59";
		//昨日
		case 3:
			String beforeDay = DateUtil.beforeDay(1);
			return beforeDay + " 00:00:00" + " - " + beforeDay + " 23:59:59";
		//最近7日
		case 4:
			String beforeWeek = DateUtil.beforeDay(7);
			return beforeWeek + " 00:00:00" + " - " + beforeWeek + " 23:59:59";
		//最近30日
		case 5:
			String beforeMonth = DateUtil.beforeDay(30);
			return beforeMonth + " 00:00:00" + " - " + beforeMonth + " 23:59:59";
		//本月
		case 6:
			String monthFirstDay = DateUtil.monthFirstDay(DateUtil.filterTime(new Date(), 1), DateUtil.filterTime(new Date(), 2));
			String monthLastDay = DateUtil.monthLastDay(DateUtil.filterTime(new Date(), 1), DateUtil.filterTime(new Date(), 2));
			return monthFirstDay + " 00:00:00" + " - " + monthLastDay + " 23:59:59";
		//上个月
		case 7:
			String previousMonthFirstDay = DateUtil.monthFirstDay(DateUtil.filterTime(DateUtil.previousMonth(), 1), DateUtil.filterTime(DateUtil.previousMonth(), 2));
			String previousMonthLastDay = DateUtil.monthLastDay(DateUtil.filterTime(DateUtil.previousMonth(), 1), DateUtil.filterTime(DateUtil.previousMonth(), 2));
			return previousMonthFirstDay + " 00:00:00" + " - " + previousMonthLastDay + " 23:59:59";
		default:
			return null;
		}
	}
	@RequestMapping("/logDetailPage")
	public String logDetailPage(int id, Model model){

		// base check
		ReturnT<String> logStatue = ReturnT.SUCCESS;
		JobLog jobLog = jobLogDao.load(id);
		if (jobLog == null) {
            throw new RuntimeException("抱歉，日志ID非法.");
		}

        model.addAttribute("triggerCode", jobLog.getTriggerCode());
        model.addAttribute("handleCode", jobLog.getHandleCode());
        model.addAttribute("executorAddress", jobLog.getExecutorAddress());
        model.addAttribute("triggerTime", jobLog.getTriggerTime().getTime());
        model.addAttribute("logId", jobLog.getId());
		return "joblog/joblog.detail";
	}

	@RequestMapping("/logDetailCat")
	@ResponseBody
	public ReturnT<LogResult> logDetailCat(String executorAddress, long triggerTime, int logId, int fromLineNum){
		try {
			ExecutorBiz executorBiz = JobDynamicScheduler.getExecutorBiz(executorAddress);
			ReturnT<LogResult> logResult = executorBiz.log(triggerTime, logId, fromLineNum);

			// is end
            if (logResult.getContent()!=null && logResult.getContent().getFromLineNum() > logResult.getContent().getToLineNum()) {
                JobLog jobLog = jobLogDao.load(logId);
                if (jobLog.getHandleCode() > 0) {
                    logResult.getContent().setEnd(true);
                }
            }

			return logResult;
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			return new ReturnT<LogResult>(ReturnT.FAIL_CODE, e.getMessage());
		}
	}

	@RequestMapping("/logKill")
	@ResponseBody
	public ReturnT<String> logKill(int id){
		// base check
		JobLog log = jobLogDao.load(id);
		JobInfo jobInfo = jobInfoDao.loadById(log.getJobId());
		if (jobInfo==null) {
			return new ReturnT<String>(500, "参数异常");
		}
		if (ReturnT.SUCCESS_CODE != log.getTriggerCode()) {
			return new ReturnT<String>(500, "调度失败，无法终止日志");
		}

		// request of kill
		ReturnT<String> runResult = null;
		try {
			ExecutorBiz executorBiz = JobDynamicScheduler.getExecutorBiz(log.getExecutorAddress());
			runResult = executorBiz.kill(jobInfo.getId());
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			runResult = new ReturnT<String>(500, e.getMessage());
		}

		if (ReturnT.SUCCESS_CODE == runResult.getCode()) {
			log.setHandleCode(ReturnT.FAIL_CODE);
			log.setHandleMsg("人为操作主动终止:" + (runResult.getMsg()!=null?runResult.getMsg():""));
			log.setHandleTime(new Date());
			jobLogDao.updateHandleInfo(log);
			return new ReturnT<String>(runResult.getMsg());
		} else {
			return new ReturnT<String>(500, runResult.getMsg());
		}
	}
	/**
	 * @Description: 跳转到清理日志页面
	 * @return   
	 * @return ModelAndView  
	 * @throws
	 * @author JornTang
	 * @date 2018年2月8日
	 */
	@RequestMapping("/toClearlog.do")
	public ModelAndView toClearlog(JobLog jobLog){
		ModelAndView view = new ModelAndView();
		JobGroup group = new JobGroup();
		JobInfo jobInfo = new JobInfo();
		if(jobLog.getJobGroup()> 0){
			group = jobGroupDao.load(jobLog.getJobGroup());
			view.addObject("group", group);
		}
		if(jobLog.getJobId()> 0){
			jobInfo = jobInfoDao.loadById(jobLog.getJobId());
			view.addObject("jobInfo", jobInfo);
		}
		
		view.setViewName("quartz/joblog/joblog-clear");
		return view;
	}
	/**
	 * @Description: 清理日志
	 * @param jobGroup
	 * @param jobId
	 * @param type
	 * @return   
	 * @return ReturnT<String>  
	 * @throws
	 * @author JornTang
	 * @date 2018年2月8日
	 */
	@RequestMapping("/clearLog.do")
	@ResponseBody
	public RespMsg clearLog(int jobGroup, int jobId, int type){

		Date clearBeforeTime = null;
		int clearBeforeNum = 0;
		if (type == 1) {
			clearBeforeTime = DateUtils.addMonths(new Date(), -1);	// 清理一个月之前日志数据
		} else if (type == 2) {
			clearBeforeTime = DateUtils.addMonths(new Date(), -3);	// 清理三个月之前日志数据
		} else if (type == 3) {
			clearBeforeTime = DateUtils.addMonths(new Date(), -6);	// 清理六个月之前日志数据
		} else if (type == 4) {
			clearBeforeTime = DateUtils.addYears(new Date(), -1);	// 清理一年之前日志数据
		} else if (type == 5) {
			clearBeforeNum = 1000;		// 清理一千条以前日志数据
		} else if (type == 6) {
			clearBeforeNum = 10000;		// 清理一万条以前日志数据
		} else if (type == 7) {
			clearBeforeNum = 30000;		// 清理三万条以前日志数据
		} else if (type == 8) {
			clearBeforeNum = 100000;	// 清理十万条以前日志数据
		} else if (type == 9) {
			clearBeforeNum = 0;			// 清理所用日志数据
		} else {
			return RespMsgUtil.returnMsg(RespEnum.ERROR, "清理类型参数异常");
		}

		jobLogDao.clearLog(jobGroup, jobId, clearBeforeTime, clearBeforeNum);
		return RespMsgUtil.returnMsg(RespEnum.SUCCESS);
	}

}
